import 'dart:async';

import 'package:connectivity/connectivity.dart';
import 'package:flutter/services.dart';
import "package:get/get.dart";

import '../gather_ctrl.dart';

class NetworkCtrl extends GetxController {
  // 阻止外界实例化
  NetworkCtrl._();

  // 内部实例化
  static NetworkCtrl _currentNetworkCtrl = NetworkCtrl._();

  // 向外界保留实例化函数
  static NetworkCtrl getInstance({int seconds}) {
    _seconds = seconds ?? 3;
    return _currentNetworkCtrl;
  }

  // 存储控制器
  static List<GatherCtrl> _gatherctrlList = [];

  // 网络断开后提醒间隔的时长（单位：秒）
  static int _seconds;

  // 网络状态（默认：true）
  RxBool networkStatus = true.obs;

  // 无网络提示组件的高度（用于各个组件修改顶部的距离）
  RxDouble topDistance = 0.0.obs;

  // 存储定时器（用于关闭指定的定时器）
  Timer _closeTimer;

  // Connectivity的实例对象
  final Connectivity _c = Connectivity();

  // 存储网络监听器实例对象（用于修改，关闭）
  static StreamSubscription<ConnectivityResult> _cs;

  @override
  void onInit() async {
    _getNetworkState(() => _listenNetwork());
    super.onInit();
  }

  // 获取网络状态
  // * [callback] 回调函数|Function|必填
  _getNetworkState(Function callback) async {
    try {
      // 查看网络情况
      ConnectivityResult _result = await _c.checkConnectivity();

      // 辨认结果
      _tellResult(_result);

      // 执行回调
      callback();
    } on PlatformException catch (e) {
      print("网络状态异常：${e.toString()}");
    }
  }

  // 监听网络变化
  void _listenNetwork() {
    _cs = _c.onConnectivityChanged.listen(
      (ConnectivityResult result) {
        // 辨认结果
        _tellResult(result);

        // true：修改网络状态
        // false：等待`_seconds`后修改网络状态（防止网络不稳定网络状态导致“闪烁”的情况）
        if (!networkStatus.value) {
          _closeTimer = Timer(
            Duration(seconds: _seconds),
            () => _update(networkStatus.value),
          );
        } else {
          // 关闭定时器
          if (_closeTimer != null) _closeTimer.cancel();

          // 更新状态
          _update(networkStatus.value);
        }
      },
    );
  }

  /// 修改网络状态
  /// #### [status] bool|网络状态|必填
  void _update(bool status) {
    // 描述网络真实情况
    networkStatus.value = status;

    // 通知各模块执行modify
    _gatherctrlList.forEach((e) => e.modify());
  }

  // 辨认结果
  // * [result] 网络情况|ConnectivityResult|必填
  void _tellResult(ConnectivityResult result) {
    switch (result) {
      case ConnectivityResult.none:
        topDistance.value = 60;
        networkStatus.value = false;
        break;
      default:
        topDistance.value = 0.0;
        networkStatus.value = true;
    }
  }

  /// 关闭网络侦听
  static void closeNetworkListen() => _cs.cancel();

  /// 将指定的控制器插入_gatherctrlList中进行观察
  /// * [c] GatherCtrl|必填|模块的控制器
  static void putCtrl(GatherCtrl c) => _gatherctrlList.add(c);

  /// 将指定的控制器从_gatherctrlList中移除
  /// * [c] GatherCtrl|必填|模块的控制器
  static void delCtrl(GatherCtrl c) => _gatherctrlList.remove(c);
}
